package hch.redesFerroviarias;

import hch.utils.Sentido;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Condition;

public class Estacion {
	protected int id;
	protected int cantidadPasajeros;
	protected int nroAndenes;
	private Semaphore semaphore;
	private Condition puedenSubir;
	private Map<Integer,Condition> puedenBajar = new HashMap<Integer,Condition>();
	private Map<Integer,Integer>   contador = new HashMap<Integer,Integer>();
	protected List<Tren> trenes = new ArrayList<Tren>();
	protected List<Tren> trenesEnEspera = new ArrayList<Tren>();
	
	public Estacion(int id, int andenes) {
		this.id = id;
		this.semaphore  = new Semaphore(andenes);
		this.nroAndenes = andenes;
		this.cantidadPasajeros = 0;
		this.puedenSubir = RedFerroviaria1.LOCK.newCondition();
	}

	//*************//
	//** METHODS **//
	//*************//
	public void obetenerAnden(){
		this.semaphore.acquireUninterruptibly();
	}
	
	public void dejarAnden(){
		this.semaphore.release();
	}
	
	public synchronized void agregarPasajero() {
		this.cantidadPasajeros ++;
	}
	
	public synchronized void restarPasajero(){
		this.cantidadPasajeros --;
	}
	
	public synchronized void addTren(Tren unTren){
		this.trenes.add(unTren);
	}
	
	public synchronized void removeTren(Tren unTren){
		this.trenes.remove(unTren);
	}
	
	public synchronized void addTrenEnEspera(Tren tren) {
		this.trenesEnEspera.add(tren);		
	}
	
	public synchronized void removeTrenEnEspera(Tren tren) {
		this.trenesEnEspera.remove(tren);		
	}
	//**************//
	//** ACCESORS **//
	//**************//
	public void sumarAlContador(Integer key){
		Integer valor = this.contador.get(key) + 1;
		this.contador.put(key, valor);
	}
	
	public Integer getCantidadQueBajan(Integer key){
		return this.contador.get(key);
	}
	
	public void putContador(Integer key){
		this.contador.put(key, 0);
	}
	public void resetearContador(Integer key){
		this.contador.put(key, 0);
	}
	
	public int getId() {
		return id;
	}
	
	public void putPermiso(Integer idTren){
		this.puedenBajar.put(idTren, RedFerroviaria1.LOCK.newCondition());
	}
	
	public Condition getPuedenBajar(Integer id){
		return this.puedenBajar.get(id);
	}
	
	public List<Tren> getTrenes() {
		return trenes;
	}
	
	public Condition getPuedenSubir() {
		return puedenSubir;
	}
	
	public List<Tren> getTrenesEnEspera() {
		return trenesEnEspera;
	}
	
	@Override
	public String toString() {
		String estacion = " | E"+id+" <"+this.nroAndenes+"> "+"("+this.cantidadPasajeros +") "+ this.trenes + "\n";
		List<Tren> trenesDerecha   = new ArrayList<Tren>();
		List<Tren> trenesIzquierda = new ArrayList<Tren>();
		for (Tren tren : this.trenesEnEspera) {
			if(tren.getSentido() == Sentido.DERECHA)
				trenesDerecha.add(tren);
			else
				trenesIzquierda.add(tren);
		}
		return " | " + trenesDerecha + "\n" + estacion + " | " + trenesIzquierda;
	}
}
